Skip to content

Conversation

@RikkiGibson
Copy link
Member

@RikkiGibson RikkiGibson commented Oct 7, 2025

Closes #80006
Depends on changes in dotnet/sdk#51373

Copy link
Member Author

@RikkiGibson RikkiGibson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submitting comments

@RikkiGibson RikkiGibson force-pushed the fbp-live-directive-diagnostics branch from 6233d9b to e774d7a Compare October 10, 2025 22:25
@RikkiGibson
Copy link
Member Author

Opened dotnet/sdk#51373. There are still a number of issues on both sdk and roslyn side when consuming this package.

@RikkiGibson RikkiGibson marked this pull request as ready for review October 28, 2025 00:42
@RikkiGibson RikkiGibson requested review from a team as code owners October 28, 2025 00:42
@RikkiGibson RikkiGibson changed the title Fbp live directive diagnostics File-based programs live directive diagnostics Oct 28, 2025
<!-- dotnet/arcade-services dependencies -->
<MicrosoftDotNetDarcLibPackageVersion>1.1.0-beta.25503.1</MicrosoftDotNetDarcLibPackageVersion>
<!-- dotnet/sdk dependencies -->
<MicrosoftDotNetFileBasedProgramsPackageVersion>10.0.200-preview.0.25556.104</MicrosoftDotNetFileBasedProgramsPackageVersion>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably setup a subscription so that we get pushed updates for this package automatically, but, want to start by just taking the version that was pushed to the feed yesterday.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ripping out all the bits that were reporting "build only diagnostics" for #: directives.


// App directives are only valid when they appear before the first C# token
var rootLeadingTrivia = root.GetLeadingTrivia();
var diagnosticBag = DiagnosticBag.Collect(out var diagnosticsBuilder);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this type is unfamiliar to me. need to figure out what that is about.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var rootLeadingTrivia = root.GetLeadingTrivia();
var diagnosticBag = DiagnosticBag.Collect(out var diagnosticsBuilder);
FileLevelDirectiveHelpers.FindLeadingDirectives(
new SourceFile(tree.FilePath, tree.GetText(context.CancellationToken)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need the entire text? Is it redundant with the leading trivia you are passing in?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added to dotnet/sdk#51487

return Diagnostic.Create(
Rule,
location: Location.Create(syntaxTree, simpleDiagnostic.Location.TextSpan),
simpleDiagnostic.Message);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inline?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the analyzer is included under this path, because we only expect/want it to run in the editor. Running it on the command line would just be redundant with what dotnet build app.cs already does.

It wouldn't cause a problem if it did somehow run on the command line, though, because in general, in a scenario where this analyzer would report an error, dotnet build app.cs would have reported an error at an earlier stage, and the compiler wouldn't run.

@RikkiGibson
Copy link
Member Author

RikkiGibson commented Nov 6, 2025

Note that one challenge with this work is: it basically takes a full day to propagate any changes in the source package over to roslyn. That really is how long it takes for an sdk change to get merged, flow into dotnet/dotnet, for unified build to run and the package to get published to the proper feed.

Obviously local package builds can be used for local runs, but, I'm talking about availability of the package in such a form that we can actually merge to roslyn main.

@RikkiGibson
Copy link
Member Author

RikkiGibson commented Nov 6, 2025

I am seeing several new public API analyzer errors under https://github.com/dotnet/roslyn/tree/b43a5601a13cb4ca3b95c66f9d13dc0448817e04/src/Features/CSharp/Portable/ExternalAccess/Pythia.

src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaSignatureHelpProviderImplementation.cs(12,20): error RS0051: Symbol 'Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api.IPythiaSignatureHelpProviderImplementation' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/PythiaSignatureHelpItemWrapper.cs(11,26): error RS0051: Symbol 'Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api.PythiaSignatureHelpItemWrapper' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/PythiaSignatureHelpItemWrapper.cs(15,37): error RS0051: Symbol 'static Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api.PythiaSignatureHelpItemWrapper.CreateTextDisplayPart(string text) -> Microsoft.CodeAnalysis.SymbolDisplayPart' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/PythiaSignatureHelpItemWrapper.cs(15,37): error RS0056: InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. (https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/PythiaSignatureHelpItemWrapper.cs(18,50): error RS0051: Symbol 'static Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api.PythiaSignatureHelpItemWrapper.CreateFromMethodGroupMethod(Microsoft.CodeAnalysis.Document document, Microsoft.CodeAnalysis.IMethodSymbol method, int position, Microsoft.CodeAnalysis.SemanticModel semanticModel, System.Collections.Generic.IList<Microsoft.CodeAnalysis.SymbolDisplayPart> descriptionParts) -> Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api.PythiaSignatureHelpItemWrapper' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/PythiaSignatureHelpItemWrapper.cs(18,50): error RS0056: InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. (https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaSignatureHelpProviderImplementation.cs(14,90): error RS0051: Symbol 'Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api.IPythiaSignatureHelpProviderImplementation.GetMethodGroupItemsAndSelectionAsync(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IMethodSymbol> accessibleMethods, Microsoft.CodeAnalysis.Document document, Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax invocationExpression, Microsoft.CodeAnalysis.SemanticModel semanticModel, Microsoft.CodeAnalysis.SymbolInfo currentSymbol, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api.PythiaSignatureHelpItemWrapper> items, int? selectedItemIndex)>' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaSignatureHelpProviderImplementation.cs(14,90): error RS0056: InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. (https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/PythiaDeclarationNameRecommender.cs(22,23): error RS0051: Symbol 'Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.PythiaDeclarationNameRecommender.PythiaDeclarationNameRecommender(System.Lazy<Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.Api.IPythiaDeclarationNameRecommenderImplementation> implementation) -> void' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/PythiaDeclarationNameRecommender.cs(22,23): error RS0056: InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. (https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/PythiaDeclarationNameRecommender.cs(26,67): error RS0051: Symbol 'Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.PythiaDeclarationNameRecommender.ProvideRecommendedNamesAsync(Microsoft.CodeAnalysis.Completion.CompletionContext completionContext, Microsoft.CodeAnalysis.Document document, Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery.CSharpSyntaxContext syntaxContext, Microsoft.CodeAnalysis.CSharp.Completion.Providers.DeclarationName.NameDeclarationInfo nameInfo, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<System.Collections.Immutable.ImmutableArray<(string name, Microsoft.CodeAnalysis.Glyph glyph)>>' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/PythiaDeclarationNameRecommender.cs(26,67): error RS0056: InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. (https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(20,26): error RS0051: Symbol 'Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.Api.PythiaDeclarationNameContext.PythiaDeclarationNameContext(Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery.CSharpSyntaxContext context) -> void' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(20,26): error RS0056: InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. (https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(24,33): error RS0051: Symbol 'Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.Api.PythiaDeclarationNameContext.Document.get -> Microsoft.CodeAnalysis.Document' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(24,33): error RS0056: InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. (https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(26,28): error RS0051: Symbol 'Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.Api.PythiaDeclarationNameContext.Position.get -> int' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(28,43): error RS0051: Symbol 'Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.Api.PythiaDeclarationNameContext.SemanticModel.get -> Microsoft.CodeAnalysis.SemanticModel' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(28,43): error RS0056: InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. (https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(33,37): error RS0051: Symbol 'Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.Api.PythiaDeclarationNameContext.LeftToken.get -> Microsoft.CodeAnalysis.SyntaxToken' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(17,34): error RS0051: Symbol 'Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.Api.IPythiaDeclarationNameRecommenderImplementation.ProvideRecommendationsAsync(Microsoft.CodeAnalysis.CSharp.ExternalAccess.Pythia.Api.PythiaDeclarationNameContext context, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<System.Collections.Immutable.ImmutableArray<string>>' is not part of the declared API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md)
src/Features/CSharp/Portable/ExternalAccess/Pythia/Api/IPythiaDeclarationNameRecommenderImplmentation.cs(17,34): error RS0056: InternalAPI.txt is missing '#nullable enable', so the nullability annotations of API isn't recorded. It is recommended to enable this tracking. (https://github.com/dotnet/roslyn-analyzers/blob/main/src/InternalApiAnalyzers/InternalApiAnalyzers.Help.md)

It's not clear to me why my change is causing this.

  • The FileBasedPrograms package does not contain any editorconfig which is enabling any "RS-prefixed" analyzer rules.
  • No InternalAPI.txt file is included in the package, nor mentioned in any targets file, etc. in the package.

Possibly, use of the FBP package is causing a PublicApiAnalyzer version to get bumped in MS.CA.CS.Features, or something? I doubt that because dotnet nuget why gives the same answer before and after taking this package:

> dotnet nuget why .\src\Features\CSharp\Portable\ Microsoft.CodeAnalysis.PublicApiAnalyzers
Project 'Microsoft.CodeAnalysis.CSharp.Features' has the following dependency graph(s) for 'Microsoft.CodeAnalysis.PublicApiAnalyzers':

  [net8.0]
  [net9.0]
  [netstandard2.0]
   │
   └─ Roslyn.Diagnostics.Analyzers (v3.11.0-beta1.24081.1)
      └─
Microsoft.CodeAnalysis.PublicApiAnalyzers (v3.11.0-beta1.24081.1)

I am planning to address by suppressing the errors under src/Features/CSharp/Portable/ExternalAccess/Pythia. Let me know if that is objectionable.

{
public const string DiagnosticId = "FileBasedPrograms";

private static readonly DiagnosticDescriptor Rule = CreateDescriptor(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should private static fields follow this convention?

Suggested change
private static readonly DiagnosticDescriptor Rule = CreateDescriptor(
private static readonly DiagnosticDescriptor s_rule = CreateDescriptor(

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjusting the name to make it look more similar to other call sites of CreateDescriptor.

private async Task<(string VirtualProjectXml, ImmutableArray<SimpleDiagnostic> Diagnostics)?> GetVirtualProjectContentImplAsync(string documentFilePath, ILogger logger, CancellationToken cancellationToken)
{
var workingDirectory = Path.GetDirectoryName(documentFilePath);
var process = dotnetCliHelper.Run(["run-api"], workingDirectory, shouldLocalizeOutput: true, keepStandardInputOpen: true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we still need to call run-api?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would want to add a method to source package for getting a virtual project and use it here before getting rid of that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, so we only wanted the source package for live diagnostics to be visible even without saving the file (which would not be easily possible with run-api). For other things, run-api still works fine. Is that correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I think it's a good idea to expand the source package, and use it to replace the task being done by this method, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to using source package instead of calling the run-api.

Namespace="Microsoft.DotNet.FileBasedPrograms" />
</ItemGroup>
<PropertyGroup>
<DefineConstants>$(DefineConstants);FILE_BASED_PROGRAMS_SOURCE_PACKAGE_GRACEFUL_EXCEPTION</DefineConstants>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this for?

Copy link
Member Author

@RikkiGibson RikkiGibson Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dotnet/sdk#51487

Usage of GracefulException, and associated compilation symbol, should be removed: dotnet/sdk#51373 (comment)

This symbol causes the source package to declare type GracefulException which is currently used in the FileBasedPrograms implementation. We want to remove the use of this type from the source package once we have the time to do so.

private async Task<(string VirtualProjectXml, ImmutableArray<SimpleDiagnostic> Diagnostics)?> GetVirtualProjectContentImplAsync(string documentFilePath, ILogger logger, CancellationToken cancellationToken)
{
var workingDirectory = Path.GetDirectoryName(documentFilePath);
var process = dotnetCliHelper.Run(["run-api"], workingDirectory, shouldLocalizeOutput: true, keepStandardInputOpen: true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to using source package instead of calling the run-api.

@RikkiGibson RikkiGibson enabled auto-merge (squash) November 7, 2025 19:55
@RikkiGibson RikkiGibson merged commit 9ff08be into dotnet:main Nov 7, 2025
28 of 29 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Nov 7, 2025
@RikkiGibson RikkiGibson deleted the fbp-live-directive-diagnostics branch November 7, 2025 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Live file-based program directive diagnostics

5 participants